/**
 * Created by FangShenglong at 2019/11/28
 * Description 用于系统页面主题切换
 */
import config from '@/common/app/config'
import elStyle from './themeData'
const ORIGINAL_COLOR = config.ORIGINAL_COLOR || '#409EFF'
// import Vue from 'vue'
// import VueLazyLoad from 'vue-lazyload'
// 该字符串为ElementUI主题的样式字符串，必须存在，换肤时将使用该样式字符串进行皮肤更换
// 该处理方案是为了解决：换肤功能必须要从cdn资源获取样式字符串的问题，如果客户端没有网络的情况下将无法完成换肤功能
const defaultStyle = elStyle

export default {
  updateTheme(newTheme, oldTheme) {
    // 要切换的主题颜色
    let newColor = config.THEME_CONFIG[newTheme] && config.THEME_CONFIG[newTheme].mainColor
    // 当前主题颜色
    let oldColor = config.THEME_CONFIG[oldTheme] && config.THEME_CONFIG[oldTheme].mainColor
    if (typeof newColor !== 'string' || typeof oldColor !== 'string') {
      return
    }
    this.updateThemeByColor({
      newTheme: newTheme,
      oldTheme: oldTheme,
      newColor: newColor,
      oldColor: oldColor,
    })
  },
  updateThemeByColor(option) {
    let { newTheme, newColor, oldColor } = option
    // 根据主题色获取配套的颜色集合
    const themeCluster = this.getThemeCluster(newColor.replace('#', ''))
    let originalCluster = this.getThemeCluster(oldColor.replace('#', ''))
    const getHandler = (variable, id) => {
      return () => {
        originalCluster = this.getThemeCluster(ORIGINAL_COLOR.replace('#', ''))
        const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)

        let styleTag = document.getElementById(id)
        if (!styleTag) {
          styleTag = document.createElement('style')
          styleTag.setAttribute('id', id)
          document.head.appendChild(styleTag)
        }
        // 替换所有目标CSS样式表
        styleTag.innerText = newStyle
      }
    }
    const chalkHandler = getHandler('chalk', 'chalk-style')
    // 如果第一次切换皮肤，从当前页面中缓存的元素中获取elementUi主题样式字符串
    if (!this.chalk) {
      this.chalk = defaultStyle.replace(/@font-face{[^}]+}/, '')
    }
    chalkHandler()
    // 过滤所有包含需要修改的style标签
    const styles = [].slice.call(document.querySelectorAll('style')).filter((style) => {
      const text = style.innerText
      return new RegExp(oldColor, 'i').test(text) && !/Chalk Variables/.test(text)
    })
    styles.forEach((style) => {
      const { innerText } = style
      if (typeof innerText !== 'string') {
        return
      }
      style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
    })
    document.body.className = config.THEME_CONFIG[newTheme].className + ' main-theme'
    window.document.documentElement.setAttribute('data-theme', newTheme)
    // 暂不使用动态更新默认图片的方案，该方案需要刷新页面
    // Vue.use(VueLazyLoad, {
    //   error: require(`@src/common/assets/theme/${newTheme}/images/default.png`),
    //   loading: require(`@src/common/assets/theme/${newTheme}/images/default.png`),
    //   preLoad: 1,
    //   attempt: 1
    // })
  },
  updateStyle(style, oldCluster, newCluster) {
    // 替换当前所有目标颜色集合，全局大小写匹配，返回替换后的整体css样式表
    let newStyle = style
    oldCluster.forEach((color, index) => {
      newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
    })
    return newStyle
  },
  getThemeCluster(themeStyle) {
    const tintColor = (color, tint) => {
      let red = parseInt(color.slice(0, 2), 16)
      let green = parseInt(color.slice(2, 4), 16)
      let blue = parseInt(color.slice(4, 6), 16)

      if (tint === 0) {
        return [red, green, blue].join(',')
      } else {
        red += Math.round(tint * (255 - red))
        green += Math.round(tint * (255 - green))
        blue += Math.round(tint * (255 - blue))

        red = red.toString(16)
        green = green.toString(16)
        blue = blue.toString(16)
        red = red.length === 1 ? '0' + red : red
        green = green.length === 1 ? '0' + green : green
        blue = blue.length === 1 ? '0' + blue : blue

        return `#${red}${green}${blue}`
      }
    }

    const shadeColor = (color, shade) => {
      let red = parseInt(color.slice(0, 2), 16)
      let green = parseInt(color.slice(2, 4), 16)
      let blue = parseInt(color.slice(4, 6), 16)

      red = Math.round((1 - shade) * red)
      green = Math.round((1 - shade) * green)
      blue = Math.round((1 - shade) * blue)

      red = red.toString(16)
      green = green.toString(16)
      blue = blue.toString(16)
      red = red.length === 1 ? '0' + red : red
      green = green.length === 1 ? '0' + green : green
      blue = blue.length === 1 ? '0' + blue : blue

      return `#${red}${green}${blue}`
    }

    const clusters = [themeStyle] // 主题色
    for (let i = 0; i <= 9; i++) {
      // 根据主题色，分成9个色阶
      clusters.push(tintColor(themeStyle, Number((i / 10).toFixed(2))))
    }
    clusters.push(shadeColor(themeStyle, 0.1))
    return clusters
  },
}
